/**
 * Created by yuris on 30.12.14.
 */
package view {
import ShopObjects.AbstractGameObjectView;
import ShopObjects.HumanView;

import com.greensock.TweenMax;
import com.greensock.easing.Linear;

import components.ShopperComponent;

import flash.geom.Point;

import flash.geom.Point;

import messages.ControllerMessage;
import messages.DebugMessage;
import messages.ModelToViewMessage;

import messages.ViewToControllerMessage;
import messages.ViewToViewMessage;

import model.Constants;

import model.objects.ShopperData;

import starling.events.EnterFrameEvent;

public class ShopperComponentMediator extends AbstractComponentMediator {
    [Inject]
    public var shopperComponent:ShopperComponent;
    private var _targetPosition:Point;
    private var _shopViewIndex:int;
    private var _insideTheShop:Boolean = false;


    override protected function onRegister():void {
        trace("Shopper mediator created: "+shopperComponent.model.id);

        (shopperComponent.model as ShopperData).updateSignal.add(this._updateSignalHandler);
        //---------DEBUG info
        //sendMessage(DebugMessage.CONSOLE_COMMAND, {type:DebugMessage.CONSOLE_SHOW_OBJECT_Z_INDEX, data:shopperComponent.view});
        //---------------------
    }

    override protected function onRemove():void {
        (shopperComponent.model as ShopperData).updateSignal.remove(this._updateSignalHandler);
    }

    private var _bufPoint:Point;
    private function _updateSignalHandler(commandName:String, param:Object):void {
        //trace("_updateSignalHandler: "+commandName+" param: "+param);
        switch (commandName){
            case Constants.OBJECT_POSITION_UPDATE_SIGNAL:
                    _bufPoint = shopperComponent.gameLayer.getLocalCoordsByQuadrant(param as Point);
                    shopperComponent.view.x = _bufPoint.x;
                    shopperComponent.view.y = _bufPoint.y;
                break;
            case Constants.OBJECT_STATUS_UPDATE_SIGNAL:
                    if(Boolean(param) == true){
                        this._shopViewIndex = shopperComponent.gameLayer.getChildIndex(shopperComponent.gameLayer.shopView);
                        shopperComponent.gameLayer.addChildAt(shopperComponent.view,this._shopViewIndex);
                        //shopperComponent.gameLayer.addShopObject(shopperComponent.view);
                        this._insideTheShop = false;
                        sendMessage(ViewToControllerMessage.SHOPPER_NEED_ACTION, shopperComponent.model);
                    } else if(shopperComponent.view.parent != null){
                        shopperComponent.view.parent.removeChild(shopperComponent.view);
                    }
                break;
            case Constants.OBJECT_ANGLE_UPDATE_SIGNAL:
                    shopperComponent.view.angle = int(param);
                break;
            case Constants.OBJECT_ACTION_UPDATE_SIGNAL:
                    this._changeAction(param);
                break;
        }
    }

    private function _changeAction(param:Object):void {
        switch (param.action as String){
            case Constants.SHOPPER_ACTION_GO:
                    if((shopperComponent.view as HumanView).currentBodyAnimation != HumanView.BODY_ANIMATION_WALK1){
                        (shopperComponent.view as HumanView).changeBodyAnimation(HumanView.BODY_ANIMATION_WALK1);
                    }
                    this._targetPosition = shopperComponent.gameLayer.getLocalCoordsByQuadrant(shopperComponent.model.position);

                    this.DEBUG_highlightQuad(shopperComponent.model.position,0x00ffff,shopperComponent.model.id);

                    //control z-index inside the shop
                    if(shopperComponent.model.position.x >= 0 && shopperComponent.model.position.y >= 0){
                        //sendMessage(ViewToViewMessage.REQUEST_Z_SORT, {object:shopperComponent.view, quad:this._targetPosition.clone()});
                    }

                    this._sortZindex();

                    TweenMax.to(shopperComponent.view,1.2,{x:this._targetPosition.x, y:this._targetPosition.y, onComplete:sendMessage, onCompleteParams:[ViewToControllerMessage.SHOPPER_NEED_ACTION, shopperComponent.model], ease:Linear.easeNone});
                    TweenMax.delayedCall(0.4,this._specialZSort);
                break;
            case Constants.SHOPPER_ACTION_WATCH_PRODUCT:
                    //sendMessage(ViewToViewMessage.REQUEST_Z_SORT, {object:shopperComponent.view, quad:this._targetPosition.clone()});

                    (shopperComponent.view as HumanView).changeBodyAnimation(HumanView.BODY_ANIMATION_STILL);
                    addHandler(ModelToViewMessage.TIME_UPDATE, HANDLER_timeUpdate);
                    this.DEBUG_highlightQuad(shopperComponent.model.position,0xff00ff,shopperComponent.model.id);

                break;
        }
    }


    private function _zSort():void {
        if(shopperComponent.model.position.x >= 0 && shopperComponent.model.position.y >= 0){
            //sendMessage(ViewToViewMessage.REQUEST_Z_SORT, {object:shopperComponent.view, quad:this._targetPosition.clone()});
        }
    }

    private function _specialZSort():void {
        //control z-index when enter the shop
        if(this._insideTheShop == false){
            //this._shopViewIndex = shopperComponent.gameLayer.getChildIndex(shopperComponent.gameLayer.shopView);
            if(shopperComponent.model.position.x >= 0 && shopperComponent.model.position.y >= 0){
                shopperComponent.gameLayer.addChildAt(shopperComponent.view,shopperComponent.gameLayer.shopViewTopIndex + 1);
                this._insideTheShop = true;
            }
        } else if(this._insideTheShop == true){
            //this._shopViewIndex = shopperComponent.gameLayer.getChildIndex(shopperComponent.gameLayer.shopView);
            if(shopperComponent.model.position.x < 0 || shopperComponent.model.position.y < 0){
                shopperComponent.gameLayer.addChildAt(shopperComponent.view,this._shopViewIndex);
                this._insideTheShop = false;
            }
        }
    }

    private function HANDLER_timeUpdate(emptyParam:Object):void {
        if(Math.random() < 0.7){
            removeHandler(ModelToViewMessage.TIME_UPDATE, this.HANDLER_timeUpdate);

            sendMessage(ViewToControllerMessage.SHOPPER_NEED_ACTION, shopperComponent.model);
        }
    }

    private var _relTopPoints:Array = [new Point(-1,-1), new Point(-1,0),  new Point(0,-1)];
    private var _relBottomPoints:Array = [new Point(0,1), new Point(1,1), new Point(1,0)];
    private var _gameObjectBuf:AbstractGameObjectView;
    private var i:int = 0;
    private var _bufObjectIndex:int;
    private var _bufShopperIndex:int;

    private function _sortZindex():void {
        for (i = 0; i < this._relTopPoints.length; i++) {
            this._bufPoint = shopperComponent.model.position.add(_relTopPoints[i] as Point);
        DEBUG_highlightQuad(this._bufPoint,0x0000ff,shopperComponent.model.id+"top"+i)
            this._gameObjectBuf = shopperComponent.gameLayer.getStaticObjectOnQuadrant(this._bufPoint);
            if(this._gameObjectBuf){
               this._bufObjectIndex = shopperComponent.gameLayer.getChildIndex(this._gameObjectBuf);
               this._bufShopperIndex = shopperComponent.gameLayer.getChildIndex(shopperComponent.view);

                if(this._bufObjectIndex > this._bufShopperIndex){
                    //shopperComponent.view.parent.swapChildren(shopperComponent.view,this._gameObjectBuf);
                    shopperComponent.view.parent.addChild(shopperComponent.view);
                }
            }
        }

        for (i = 0; i < this._relBottomPoints.length; i++) {
            this._bufPoint = shopperComponent.model.position.add(_relBottomPoints[i] as Point);
            DEBUG_highlightQuad(this._bufPoint,0xff0000,shopperComponent.model.id+"bottom"+i)
            this._gameObjectBuf = shopperComponent.gameLayer.getStaticObjectOnQuadrant(this._bufPoint);
            if(this._gameObjectBuf){
                this._bufObjectIndex = shopperComponent.gameLayer.getChildIndex(this._gameObjectBuf);
                this._bufShopperIndex = shopperComponent.gameLayer.getChildIndex(shopperComponent.view);

                if(this._bufObjectIndex < this._bufShopperIndex){
                    //shopperComponent.view.parent.swapChildren(shopperComponent.view,this._gameObjectBuf);
                    shopperComponent.view.parent.addChildAt(shopperComponent.view,this._bufObjectIndex);
                }
            }
        }

        //TODO: make proper sorting (via Controller)
    }

    private function DEBUG_highlightQuad(position:Point, color:uint, id:String = null):void {
        sendMessage(DebugMessage.HIGHLIGHT_QUAD,{position:position, color:color, id:id});
    }


}
}
